home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Mac Game Programming Gurus
/
TricksOfTheMacGameProgrammingGurus.iso
/
Book Chapters
/
03 - Advanced Graphics
/
Example 2
/
sprite.c
< prev
next >
Wrap
Text File
|
1995-06-02
|
5KB
|
202 lines
//
// File: sprite.c
//
// This file contains the routines to draw the sprites
//
// 2/19/95 -- Created by Mick
//
// include files
#include "global.h"
#include "sprite.h"
#include "main.h"
// defines for this file
// global function declarations
tSpriteInfo *loadSprite( signed short inSpriteResID, signed short inMaskResID );
void disposeSprite( tSpriteInfo *inSpriteInfo );
void startSpriteDraw( Rect *inClipRect, PixMapHandle inDestPixMap );
void endSpriteDraw( void );
void drawSprite( tSpriteInfo *inSpriteInfo, Point inWhere );
// global data owned by this file
// local function declarations
// static data
RgnHandle sOldClipRgn; // storage space for the clip region before the startSpriteDraw call
PixMapHandle sDestPixMap; // where we are going to draw this data
// functions
//
// loadSprite -
//
// Loads/allocates all the data for a sprite.
//
tSpriteInfo *loadSprite( signed short inSpriteResID, signed short inMaskResID )
{
tSpriteInfo *newSprite; // the new sprite data
PicHandle spritePict; // the sprite/mask picture
CGrafPtr oldCPort; // the graf port that is in place when we are called
GrafPtr oldPort; // the b&w port that we are saving
GDHandle oldDevice; // the gdevice that is in place when we are called
// create the sprite info record
newSprite = ( tSpriteInfo * )NewPtr( sizeof( tSpriteInfo ) );
// load the pict
spritePict = GetPicture( inSpriteResID );
if ( spritePict == ( PicHandle )kNil )
{
// if it did not load, drop into the debugger -- real programs would have error checking
Debugger();
}
// copy its bounds rect
newSprite->fSpriteRect = ( *spritePict )->picFrame;
// create a gworld for it
NewGWorld( &newSprite->fSpriteWorld, 8, &( newSprite->fSpriteRect ),
gAppColorTable, ( GDHandle )kNil, keepLocal );
// extract the pixmap handle
newSprite->fSpritePix = GetGWorldPixMap( newSprite->fSpriteWorld );
// save the current port and gdevice
GetGWorld( &oldCPort, &oldDevice );
// set the offscreen buffer as current ( and lock the pixel map )
SetGWorld( newSprite->fSpriteWorld, ( GDHandle )kNil );
LockPixels( newSprite->fSpritePix );
// draw the picture
EraseRect( &( newSprite->fSpriteRect ) );
DrawPicture( spritePict, &( newSprite->fSpriteRect ) );
// restore the current port and gdevice
UnlockPixels( newSprite->fSpritePix );
SetGWorld( oldCPort, oldDevice );
// dump this pict
ReleaseResource( ( Handle )spritePict );
// load the mask pict
spritePict = GetPicture( inMaskResID );
// allocate a new port
newSprite->fMaskPort = ( GrafPtr )NewPtr( sizeof( GrafPort ) );
OpenPort( newSprite->fMaskPort );
// fiddle with its port bits
newSprite->fMaskPort->portBits.bounds = newSprite->fSpriteRect;
newSprite->fMaskPort->portBits.rowBytes = ( ( newSprite->fSpriteRect.right - newSprite->fSpriteRect.left ) + 15 ) / 8;
newSprite->fMaskPort->portBits.baseAddr =
NewPtr( newSprite->fMaskPort->portBits.rowBytes * ( newSprite->fSpriteRect.bottom - newSprite->fSpriteRect.top ) );
// save the port
GetPort( &oldPort );
// set the new port
SetPort( newSprite->fMaskPort );
// draw the picture
EraseRect( &( newSprite->fSpriteRect ) );
DrawPicture( spritePict, &( newSprite->fSpriteRect ) );
// restore the old port
SetPort( oldPort );
// dump this pict
ReleaseResource( ( Handle )spritePict );
// return the new sprite!
return newSprite;
}
//
// disposeSprite -
//
// Disposes/releases all the memory used in a sprite
//
void disposeSprite( tSpriteInfo *inSpriteInfo )
{
// dump the gworld
DisposeGWorld( inSpriteInfo->fSpriteWorld );
// dump the memory from the bitmap
DisposePtr( ( Ptr )( inSpriteInfo->fMaskPort->portBits.baseAddr ) );
// dump the port
DisposePtr( ( Ptr )( inSpriteInfo->fMaskPort ) );
// free the structure
DisposePtr( ( Ptr )inSpriteInfo );
}
//
// startSpriteDraw -
//
// Prepare the sprite draw. Assumes that the port is set to the destination port.
//
void startSpriteDraw( Rect *inClipRect, PixMapHandle inDestPixMap )
{
// save the current port's clip region
sOldClipRgn = NewRgn();
GetClip( sOldClipRgn );
// set the clip region to be the passed in rect
ClipRect( inClipRect );
// save the pix map info (so we can use it)
sDestPixMap = inDestPixMap;
}
//
// endSpriteDraw -
//
// End the sprite draw sequence.
//
void endSpriteDraw( void )
{
// restore the old clip region
SetClip( sOldClipRgn );
// dump the region
DisposeRgn( sOldClipRgn );
}
//
// drawSprite -
//
// Draw the sprite in the port.
//
void drawSprite( tSpriteInfo *inSpriteInfo, Point inWhere )
{
Rect destRect; // where we want to draw the sprite
// calculate the destination rect
destRect = inSpriteInfo->fSpriteRect;
OffsetRect( &destRect, inWhere.h, inWhere.v );
// draw the sprite
CopyMask( ( BitMap * )( *( inSpriteInfo->fSpritePix ) ), &( inSpriteInfo->fMaskPort->portBits ),
( BitMap * )( *sDestPixMap ), &( inSpriteInfo->fSpriteRect ), &( inSpriteInfo->fSpriteRect ), &destRect );
}